package com.author.document.model;

import java.io.IOException;
import java.util.ArrayList;

import javax.swing.event.UndoableEditListener;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Element;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleContext;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.HTMLEditorKit.Parser;
import javax.swing.text.html.StyleSheet;
import javax.swing.undo.UndoManager;

import org.w3c.dom.*;

import com.author.document.view.ListView;
import com.author.util.ServiceRegister;

public final class ExtendedDocument extends HTMLDocument {
	private StyleContext		styleContext;
	public static final String	LIST_ELEMENT			= "LIST_ELEMENT";

	/** Insets associated with the paragraph element */
	public static final String	PARAGRAPH_LEFT_INSET	= "LEFT_INSET";
	public static final String	PARAGRAPH_RIGHT_INSET	= "RIGHT_INSET";
	public static final String	PARAGRAPH_TOP_INSET		= "TOP_INSET";
	public static final String	PARAGRAPH_BOTTOM_INSET	= "BOTTOM_INSET";

	/** LEFT indent of the paragraph relative to the left margin */
	public static final Object	PARAGRAPH_LEFT_INDENT	= "LEFT_INDENT";

	/** Maximum width of a single char (assuming monospaced font) {#{@value} */
	public static final float	CHARACTER_WIDTH			= (float) 8.0;

	/* Undo Manager for the document */
	private UndoManager			undo;
	
	/* Service provider for document. This object is responsible for listening
	 * to changes taking place in the document. All objects which depend on the
	 * changes taking place in the document, should subscribe to this object so
	 * that can receive changes taking place in the document.
	 */
	private static DocumentService docService = null;
	
	public ExtendedDocument(StyleContext stylecontext) {
		super();
		styleContext = stylecontext;
	}

	public ExtendedDocument() {
		super();

		if (undo == null) {
			undo = new UndoManager();
		}

		/* Add undo manager for document */
		this.addUndoableEditListener(undo);
	}

	public ExtendedDocument(StyleSheet s) {
		super(s);

		if (undo == null) {
			undo = new UndoManager();
		}

		/* Add undo manager for document */
		this.addUndoableEditListener(undo);
		
		try {
			ExtendedDocument.docService = 
				new DocumentService (ServiceRegister.getServiceRegister(), 
						this);
			this.addDocumentListener(docService);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public StyleContext getStyleContext() {
		return styleContext;
	}

	public void setStyleContext(StyleContext stylecontext) {
		styleContext = stylecontext;
	}

	/**
	 * @return UndoManager for the custom HTML document
	 */
	public UndoableEditListener getUndoManager() {
		return undo;
	}

	@Override
	public Parser getParser() {
		HTMLEditorKit.Parser parser = null;
		try {
			Class<?> c = Class.forName("javax.swing.text.html.parser.ParserDelegator");
			parser = (Parser) c.newInstance();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}

		return parser;
	}

	@Override
	public void insert(int offset, DefaultStyledDocument.ElementSpec[] data)
			throws BadLocationException {
		super.insert(offset, data);
	}
}
